/**
 * date:2020/07/14
 * author:Yinzhx
 * version:1.0
 * description:layuimini ab扩展类
 */
layui.define(["jquery", "layer", "form"], function (exports) {
    var $ = layui.$,
        form = layui.form,
        layer = layui.layer;

    var ab = {
        /**
         * 日期处理
         getDate                    获取日期对象
         format                     格式化日期
         mergeDateTime              组合日期
         isToday                    是否是当天
         isFriday                    是否是星期五
         isWeekend                    是否是周末
         getWeekFirstDay            获取本周第一天
         getWeekLastDay                获取本周最后一天
         compare                    比较2个日期字符串
         toTwoNumber                转换成至少2位的数字字符串，不足2位以0补齐
         newDate                    获取当前日期指定格式的字符串
         getDisDate                    获取指定日期往后天数的日期字符串
         getDisAllDate                获取指定日期往后天数的日期字符串(包含时分秒）
         daysDiff                    获取2个日期的天数差
         hoursDiff                    获取2个日期的小时差
         nightsDiff                    获取2个日期的夜晚差
         getWeek                    获取指定日期的星期几文本
         getMonthFirstDay            获取当月第一天
         getMonthLastDay            获取当月最后一天
         getWeeks                    获取指定时间的星期“几”文本
         toFestival                    获取节假日文本
         isCheckInToday                检查是否是今天
         addZero                    补零（小于10）
         getMilliseconds            获取指定日期（包含时分秒）的时间轴
         getTimeString                获取指定日期的时分格式(例如："2016-01-01 23:59"，"2016-01-01")
         date                        根据指定日期字符串返回日期对象
         getCNWeek                    获取中文星期描述
         jumpDate                    获取跳过指定天数的日期（例如："2017-07-31 23:59"）
         jumpHour                    获取跳过指定小时的日期（例如："2017-07-31 23:59"）
         jumpMonth                    获取跳过指定月份的日期（例如："2017-07-31 23:59"）
         createDateArray            创建指定日期范围内的日期数组
         getFirstAndLastMonthDay    获取指定日期当月第一天和最后一天的对象
         */
        dateUtil: function () {
            var _dateUtil = {
                /**
                 * 获取日期对象
                 * @param dateStr ：2017-7-1
                 * @returns {Date}
                 */
                getDate: function (dateStr) {
                    var t, n, r;
                    t = $.trim(dateStr).split(" ");
                    n = t[0].split(/[\-\/]/);
                    r = t[1] ? t[1].split(":") : [0, 0, 0];
                    return new Date(n[0], n[1] - 1, n[2], r[0], r[1], r[2] ? r[2] : 0)
                },
                /**
                 * 格式化日期
                 * @param date  日期
                 * @param fmt   年：yy,月：MM,日：dd,小时：hh,分钟:mm,秒:ss   例如:yyyy-MM-dd，yyyy/MM/dd hh:mm:ss
                 * @returns {*} 格式化后的日期字符串,同上：2017-07-27,2017/07/27 10:13:13
                 */
                format: function (date, fmt) {
                    t = _dateUtil._getDate(date);
                    var r = {
                        "M+": t.getMonth() + 1,
                        "d+": t.getDate(),
                        "h+": t.getHours(),
                        "m+": t.getMinutes(),
                        "s+": t.getSeconds(),
                        "q+": Math.floor((t.getMonth() + 3) / 3),
                        S: t.getMilliseconds()
                    };
                    if (typeof fmt == 'undefined') fmt = 'yyyy-MM-dd';
                    if (/(y+)/.test(fmt)) {
                        fmt = fmt.replace(RegExp.$1, (t.getFullYear() + "").substr(4 - RegExp.$1.length))
                    }
                    for (var i in r) if ((new RegExp("(" + i + ")")).test(fmt)) {
                        fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? r[i] : ("00" + r[i]).substr(("" + r[i]).length))
                    }
                    return fmt;
                },
                /**
                 * 组合日期
                 * @param dt1   第一个日期字符串
                 * @param dt2   第二个日期字符串
                 * @returns {string}    返回组合后的日期字符串
                 */
                mergeDateTime: function (dt1, dt2) {
                    return dt1 + " " + dt2
                },
                /**
                 * 是否是当天
                 * @param dt1   第一个日期
                 * @param dt2   第二个日期
                 * @returns {boolean}
                 */
                isToday: function (dt1, dt2) {
                    return _dateUtil.compare(dt1, dt2) == "0" ? true : false
                },
                /**
                 * 是否是星期五
                 * @param dateStr   日期字符串
                 * @returns {boolean}   是与否
                 */
                isFriday: function (dateStr) {
                    var n = _dateUtil.getDate(dateStr).getDay();
                    if (n == 5) {
                        return true
                    }
                    return false
                },
                /**
                 * 是否是周末
                 * @param dateStr   日期字符串
                 * @returns {boolean}   是与否
                 */
                isWeekend: function (dateStr) {
                    var n = _dateUtil.getDate(dateStr).getDay();
                    if (n == 0 || n == 6) {
                        return true
                    }
                    return false
                },
                /**
                 * 获取本周第一天
                 * @param dateStr   日期字符串
                 * @returns {string}    本周第一天字符串
                 */
                getWeekFirstDay: function (dateStr) {
                    var n = _dateUtil.getDate(t).getDay(),
                        r = "";
                    if (n == 1 || n == 2 || n == 3 || n == 4 || n == 5 || n == 6) {
                        r = _dateUtil.getDisDate(t, -(n - 1))
                    } else if (n == 0) {
                        r = _dateUtil.getDisDate(t, -6)
                    }
                    return r
                },
                /**
                 * 获取本周最后一天
                 * @param dateStr   日期字符串
                 * @returns {*}     本周最后一天字符串
                 */
                getWeekLastDay: function (dateStr) {
                    var n = _dateUtil.getDate(dateStr).getDay();
                    return _dateUtil.getDisDate(dateStr, (7 - n) % 7)
                },
                /**
                 * 比较2个日期字符串
                 * @param dt1   第一个日期字符串
                 * @param dt2   第二个日期字符串
                 * @returns {*} 大于：1，等于：0，小于：-1
                 */
                compare: function (dt1, dt2) {
                    t = _dateUtil._getDate(dt1);
                    n = _dateUtil._getDate(dt2);
                    var r = t.getTime(),
                        i = n.getTime();
                    if (r > i) {
                        return "1"
                    } else if (r < i) {
                        return "-1"
                    } else {
                        return "0"
                    }
                },
                /**
                 * 转换成至少2位的数字字符串，不足2位以0补齐
                 * @param numStr    10进制数字字符串
                 * @returns {string}
                 */
                toTwoNumber: function (numStr) {
                    e = parseInt(numStr, 10);
                    if (e < 10) {
                        return "0" + e
                    }
                    return e + "";
                },
                /**
                 * 获取当前日期指定格式的字符串
                 * @param fmt   年：yy,月：MM,日：dd,小时：hh,分钟:mm,秒:ss   例如:yyyy-MM-dd，yyyy/MM/dd hh:mm:ss
                 * @returns {*}
                 */
                newDate: function (fmt) {
                    var n = new Date;
                    return _dateUtil.format(n, fmt);
                },
                /**
                 * 获取指定日期往后天数的日期字符串
                 * @param dateStr   日期字符串
                 * @param day       增加的天数
                 * @param fmt       日期格式（*可选）。年：yy,月：MM,日：dd,小时：hh,分钟:mm,秒:ss   例如:yyyy-MM-dd，yyyy/MM/dd hh:mm:ss
                 * @returns {*}
                 */
                getDisDate: function (dateStr, day, fmt) {
                    var i = _dateUtil._getDate(dateStr);
                    var s = i.getTime() + day * 24 * 60 * 60 * 1e3;
                    var o = fmt ? _dateUtil.format(new Date(s), fmt) : _dateUtil.format(new Date(s), "yyyy-MM-dd");
                    return o
                },
                /**
                 * 获取指定日期往后天数的日期字符串(包含时分秒）
                 * @param dateStr   日期字符串
                 * @param day       增加的天数
                 * @param fmt       日期格式（*可选）。年：yy,月：MM,日：dd,小时：hh,分钟:mm,秒:ss   例如:yyyy-MM-dd，yyyy/MM/dd hh:mm:ss
                 * @returns {*}
                 */
                getDisAllDate: function (dateStr, day, fmt) {
                    var i = _dateUtil._getDate(dateStr);
                    var s = i.getTime() + day * 24 * 60 * 60 * 1e3;
                    var o = fmt ? _dateUtil.format(new Date(s), fmt) : _dateUtil.format(new Date(s), "yyyy-MM-dd hh:mm:ss");
                    return o
                },
                /**
                 * 获取日期
                 * @param dateStr   日期字符串
                 * @returns {*}
                 * @private
                 */
                _getDate: function (dateStr) {
                    if (typeof dateStr == "string") {
                        return _dateUtil.getDate(dateStr)
                    }else if(typeof dateStr == 'number'){
                        return new Date(dateStr)
                    }
                    return dateStr;
                },
                /**
                 * 获取2个日期的天数差
                 * @param dt1   第一个日期，日期格式必须为：yyyy-MM-dd
                 * @param dt2   第二个日期，日期格式必须为：yyyy-MM-dd
                 * @returns {Number|*}
                 */
                daysDiff: function (dt1, dt2) {
                    var n, r, i, s;
                    n = dt1.split(" ")[0].split("-");
                    r = new Date(n[0], n[1] - 1, n[2]);
                    n = dt2.split(" ")[0].split("-");
                    i = new Date(n[0], n[1] - 1, n[2]);
                    s = parseInt(Math.abs(i - r) / 1e3 / 60 / 60 / 24);
                    return s
                },
                /**
                 * 获取2个日期的小时差
                 * @param dt1   第一个日期，年月日或年月日时分秒
                 * @param dt2   第二个日期，年月日或年月日时分秒
                 * @param r
                 * @returns {*}
                 */
                hoursDiff: function (dt1, dt2, r) {
                    var i, s, o;
                    i = _dateUtil._getDate(dt1);
                    s = _dateUtil._getDate(dt2);
                    o = parseFloat(Math.abs(i - s) / 1e3 / 60 / 60);
                    if (r == "ceil") {
                        return Math.ceil(o)
                    }
                    return o
                },
                /**
                 * 获取2个日期的夜晚差
                 * @param dt1   第一个日期
                 * @param dt2   第二个日期
                 * @returns {Number|*}
                 */
                nightsDiff: function (dt1, dt2) {
                    var n, r, i, s;
                    n = dt1.split(" ")[0].split("-");
                    r = new Date(n[0], n[1] - 1, n[2]);
                    n = dt2.split(" ")[0].split("-");
                    i = new Date(n[0], n[1] - 1, n[2]);
                    s = parseInt(Math.abs(i - r) / 1e3 / 60 / 60 / 24);
                    if (s === 0) {
                        s = 1
                    }
                    return s
                },
                /**
                 * 获取指定日期的星期几文本
                 * @param dateStr   日期字符串
                 * @returns {string}
                 */
                getWeek: function (dateStr) {
                    var t = _dateUtil._getDate(dateStr);
                    var n = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
                    var r = t.getDay();
                    return n[r]
                },
                /**
                 * 获取当月第一天
                 * @param dateStr
                 * @returns {*}
                 */
                getMonthFirstDay: function (dateStr) {
                    var n = dateStr.split("-")[0];
                    var r = dateStr.split("-")[1];
                    return _dateUtil.format(new Date(n, r - 1, 1), "yyyy-MM-dd")
                },
                /**
                 * 获取当月最后一天
                 * @param dateStr
                 * @returns {*}
                 */
                getMonthLastDay: function (dateStr) {
                    var n = dateStr.split("-")[0];
                    var r = dateStr.split("-")[1];
                    var i = n;
                    var s = r++;
                    if (r > 12) {
                        s -= 12;
                        i++
                    }
                    var o = new Date(i, s, 1);
                    return _dateUtil.format(new Date(o.getTime() - 1e3 * 60 * 60 * 24), "yyyy-MM-dd")
                },
                /**
                 * 获取指定时间的星期“几”文本
                 * @param dateStr   日期字符串
                 * @returns {string}
                 */
                getWeeks: function (dateStr) {
                    var t = _dateUtil._getDate(dateStr);
                    var n = ["日", "一", "二", "三", "四", "五", "六"];
                    var r = t.getDay();
                    return n[r]
                },
                /**
                 * 获取节假日文本
                 * @param dateStr   日期字符串
                 * @returns {*}
                 */
                toFestival: function (dateStr) {
                    return ab.festivalConfig[dateStr];
                },
                /**
                 * 检查是否是今天
                 * @param arr   日期数组
                 * @returns {*}
                 */
                isCheckInToday: function (arr) {
                    var n = "",
                        r = arr.length,
                        i = arr.sort();
                    if (r == 0) {
                        return true
                    }
                    var s = _dateUtil.newDate("yyyy-MM-dd");
                    if (r == 1) {
                        var o = _dateUtil.isToday(i[0], s);
                        return o
                    }
                    n = i[0];
                    var o = _dateUtil.isToday(n, s);
                    if (!o) {
                        return false
                    }
                    for (var u = 1; u < r; u++) {
                        if (_dateUtil.daysDiff(n, i[u]) != 1) {
                            return false
                        }
                        n = i[u]
                    }
                    return true
                },
                /**
                 * 补零（小于10）
                 * @param num
                 * @returns {string}
                 */
                addZero: function (num) {
                    return num < 10 ? "0" + num : num
                },
                /**
                 * 获取指定日期（包含时分秒）的时间轴
                 * @param dateStr
                 * @returns {number}
                 */
                getMilliseconds: function (dateStr) {
                    var t = dateStr.split(" "),
                        n = t[0].split("-"),
                        r = [];
                    if (t.length === 1) {
                        return (new Date(n[0], n[1] - 1, n[2])).getTime()
                    } else if (t.length === 2) {
                        r = t[1].split(":");
                        switch (r.length) {
                            case 1:
                                return (new Date(n[0], n[1] - 1, n[2], r[0])).getTime();
                            case 2:
                                return (new Date(n[0], n[1] - 1, n[2], r[0], r[1])).getTime();
                            case 3:
                                return (new Date(n[0], n[1] - 1, n[2], r[0], r[1], r[2])).getTime()
                        }
                    }
                },
                /**
                 * 获取指定日期的时分格式(例如："2016-01-01 23:59"，"2016-01-01")
                 * @param dateStr   日期字符串
                 * @param flag      是否展示时分
                 * @returns {string}
                 */
                getTimeString: function (dateStr, flag) {
                    var r = new Date(dateStr),
                        i = [],
                        s = [];
                    i[0] = r.getFullYear();
                    i[1] = _dateUtil.addZero(r.getMonth() + 1);
                    i[2] = _dateUtil.addZero(r.getDate());
                    s[0] = _dateUtil.addZero(r.getHours());
                    s[1] = _dateUtil.addZero(r.getMinutes());
                    if (arguments.length < 2 || flag) {
                        return i.join("-") + " " + s.join(":")
                    } else {
                        return i.join("-")
                    }
                },
                /**
                 * 根据指定日期字符串返回日期对象
                 * @param dateStr
                 * @returns {{getYear: getYear, getMonth: getMonth, getDate: getDate, getHour: getHour, getMinute: getMinute, getDay: getDay, getFormatDate: getFormatDate}}
                 */
                date: function (dateStr) {
                    var n = dateStr.split(" "),
                        r = n[0].split("-"),
                        i = n[1] ? n[1].split(":") : [],
                        s = _dateUtil;
                    return {
                        getYear: function () {
                            return r[0]
                        },
                        getMonth: function () {
                            return r[1]
                        },
                        getDate: function () {
                            return r[2]
                        },
                        getHour: function () {
                            return i.length > 0 ? i[0] : ""
                        },
                        getMinute: function () {
                            return i.length > 1 ? i[1] : ""
                        },
                        getDay: function () {
                            var e = s.getMilliseconds(t);
                            return (new Date(e)).getDay()
                        },
                        getFormatDate: function () {
                            return n[0]
                        }
                    }
                },
                /**
                 * 获取中文星期几描述
                 * @param e     星期几索引
                 * @param t     是否展示完整的描述
                 * @returns {Blob|string|Array.<T>|ArrayBuffer|*}
                 */
                getCNWeek: function (e, t) {
                    var n = {
                        0: "星期日",
                        1: "星期一",
                        2: "星期二",
                        3: "星期三",
                        4: "星期四",
                        5: "星期五",
                        6: "星期六"
                    };
                    return t ? n[e] : n[e].slice(2)
                },
                /**
                 * 获取跳过指定天数的日期（例如："2017-07-31 23:59"）
                 * @param dateStr   指定日期
                 * @param n         跳过天数
                 * @returns {*|string}
                 */
                jumpDate: function (dateStr, n) {
                    var r = _dateUtil.getMilliseconds(dateStr),
                        n = arguments.length === 1 ? 1 : n,
                        i = dateStr.indexOf(":") !== -1;
                    return _dateUtil.getTimeString(r + 3600 * 24 * 1e3 * n, i)
                },
                /**
                 * 获取跳过指定小时的日期（例如："2017-07-31 23:59"）
                 * @param dateStr   指定日期
                 * @param n         指定小时
                 * @returns {*|string}
                 */
                jumpHour: function (dateStr, hour) {
                    var r = _dateUtil.getMilliseconds(dateStr),
                        n = arguments.length === 1 ? 1 : hour;
                    return _dateUtil.getTimeString(r + 3600 * 1e3 * n)
                },
                /**
                 * 获取跳过指定月份的日期（例如："2017-07-31 23:59"）
                 * @param dateStr   指定日期
                 * @param month     指定月份
                 * @param flag      是否显示时分
                 * @returns {*}
                 */
                jumpMonth: function (dateStr, month, flag) {
                    var i = new Date(dateStr),
                        n = arguments.length === 1 ? 1 : month,
                        s = _dateUtil.getTimeString(i.setMonth(i.getMonth() + n));
                    if (flag) {
                        return s
                    } else {
                        return s.slice(0, 10)
                    }
                },
                /**
                 * 创建指定日期范围内的日期数组
                 * @param dt1   第一个日期
                 * @param dt2   第二个日期
                 * @returns {Array} 日期数组
                 */
                createDateArray: function (dt1, dt2) {
                    var r = _dateUtil.daysDiff(dt1, dt2) + 1;
                    var i = dt1.split("-");
                    var s = i[0];
                    var o = i[1];
                    var u = i[2];
                    var a = [];
                    for (var f = 0; f < r; f++) {
                        if (u > (new Date(s, o, 0)).getDate()) {
                            u = 1;
                            o++;
                            if (o > 12) {
                                o = 1;
                                s++
                            }
                        }
                        a.push(s + "-" + _dateUtil.toTwoNumber(o) + "-" + _dateUtil.toTwoNumber(u));
                        u++
                    }
                    return a
                },
                /**
                 * 获取指定日期当月第一天和最后一天的对象
                 * @param dateStr   指定日期
                 * @returns {{firstDate: string, lastDate: string}}
                 */
                getFirstAndLastMonthDay: function (dateStr) {
                    var t = dateStr.split("-"),
                        n = t[0],
                        r = t[1],
                        i = new Date(n, r, 0),
                        s = n + "-" + r + "-01",
                        o = n + "-" + r + "-" + i.getDate();
                    return {
                        firstDate: s,
                        lastDate: o
                    }
                }
            };
            return _dateUtil;
        }(),
        /**
         * util 工具类
         */
        util: function () {
            var exports = {
                uuid: {
                    set: function () {
                        var value;
                        if (this.isValid(arguments[0])) {
                            value = arguments[0];
                        } else {
                            value = this.empty();
                        }
                        $(this).data("value", value);
                        return value;
                    },
                    empty: function () {
                        return "00000000-0000-0000-0000-000000000000";
                    },
                    isEmpty: function (gid) {
                        return gid == ab.util.uuid.empty() || typeof (gid) == 'undefined' || gid == null || gid == '';
                    },
                    isValid: function (value) {
                        var rGx = new RegExp("\\b(?:[A-F0-9]{8})(?:-[A-F0-9]{4}){3}-(?:[A-F0-9]{12})\\b");
                        return rGx.exec(value) != null;
                    },
                    newId: function () {
                        var value;
                        if (arguments.length == 1 && this.IsValid(arguments[0])) {
                            $(this).data("value", arguments[0]);
                            value = arguments[0];
                            return value;
                        }
                        var res = [], hv;
                        var rgx = new RegExp("[2345]");
                        for (var i = 0; i < 8; i++) {
                            hv = (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
                            if (rgx.exec(i.toString()) != null) {
                                if (i == 3) {
                                    hv = "6" + hv.substr(1, 3);
                                }
                                res.push("-");
                            }
                            res.push(hv);//.toUpperCase());
                        }
                        value = res.join('');
                        $(this).data("value", value);
                        return value;
                    },
                    value: function () {
                        if ($(this).data("value")) {
                            return $(this).data("value");
                        }
                        var val = this.newId();
                        $(this).data("value", val);
                        return val;
                    }
                },
                /**
                 * 根据key获取value
                 * @param key
                 */
                request: function (key) {
                    var search = location.search.slice(1);
                    var arr = search.split("&");
                    for (var i = 0; i < arr.length; i++) {
                        var ar = arr[i].split("=");
                        if (ar[0] == key) {
                            if (decodeURI(ar[1]) == 'undefined') {
                                return "";
                            } else {
                                return decodeURI(ar[1]);
                            }
                        }
                    }
                    return "";
                },
                /**
                 * 下载方法
                 * @param url       url地址
                 * @param data      参数对象
                 * @param method    请求方式：post,get
                 */
                download: function (url, data, method) {
                    if (url && data) {
                        data = typeof data == 'string' ? data : $.param(data);
                        var inputs = '';
                        $.each(data.split('&'), function () {
                            var pair = this.split('=');
                            inputs += '<input type="hidden" name="' + pair[0] + '" value="' + pair[1] + '" />';
                        });
                        $('<form action="' + url + '" method="' + (method || 'post') + '">' + inputs + '</form>').appendTo('body').submit().remove();
                    }
                },
                /**
                 * 表单提交
                 * @param options
                 */
                submitForm: function (options) {
                    var g = this;
                    var defaults = {
                        url: "",
                        param: [],
                        type: "POST",
                        loadingEle: null,
                        loading: "正在努力提交数据,请稍后...",
                        showTips: true,
                        success: null,
                        error: null
                    };
                    var options = $.extend(defaults, options);
                    // g.loading(true, options.loading);
                    if (options.loadingEle != null)
                        options.loadingEle.mLoading({text: options.loading});
                    ab.ajax({
                        url: options.url,
                        data: options.data,
                        type: options.type,
                        success: function (data) {
                            if (data.code != undefined && data.code === "200") {
                                options.success(data);
                                if (options.showTips) ab.window.msg(data.msg, data.code);
                            } else {
                                if (options.error != null) options.error(data);
                                ab.window.alert(data.msg, data.code);
                            }
                        },
                        error: function (XMLHttpRequest, textStatus, errorThrown) {
                            ab.window.thrown(XMLHttpRequest);
                            if (options.error != null) options.error();
                        },
                        beforeSend: function () {
                            // g.loading(true, options.loading);
                        },
                        complete: function () {
                            // g.loading(false);
                        }
                    });
                },
                /**
                 * 表单删除
                 * @param options
                 */
                deleteForm: function (options) {
                    var defaults = {
                        prompt: "注：您确定要删除该项数据吗？",
                        url: "",
                        param: [],
                        type: "POST",
                        loadingEle: null,
                        loading: "正在删除数据...",
                        success: null,
                        close: true
                    };
                    var options = $.extend(defaults, options);
                    ab.window.confirm(options.prompt, function (r, dIndex) {
                        if (r) {
                            ab.ajax({
                                url: options.url,
                                data: options.data,
                                type: options.type,
                                success: function (data) {
                                    if (data.code == "200") {
                                        options.success(data);
                                        layer.close(dIndex);
                                        ab.window.msg(data.msg, data.code);
                                    } else {
                                        ab.window.alert(data.msg, data.code);
                                    }
                                },
                                error: function (XMLHttpRequest, textStatus, errorThrown) {
                                    ab.window.thrown(XMLHttpRequest);
                                },
                                beforeSend: function () {
                                    // ab.loading(true, options.loading);
                                },
                                complete: function () {
                                    // ab.loading(false);
                                }
                            });
                        }
                    });
                },
                /**
                 * 表单验证
                 */
                formRequired: function () {
                    var verifyList = document.querySelectorAll("[lay-verify]");
                    if (verifyList.length > 0) {
                        $.each(verifyList, function (i, v) {
                            var verify = $(this).attr('lay-verify');
                            // todo 必填项处理
                            if (verify === 'required') {
                                var label = $(this).parent().prev();
                                if (label.is('label') && !label.hasClass('required')) {
                                    label.addClass('required');
                                }
                                if ($(this).attr('lay-reqtext') === undefined && $(this).attr(
                                    'placeholder') !== undefined) {
                                    $(this).attr('lay-reqtext', $(this).attr('placeholder'));
                                }
                                if ($(this).attr('placeholder') === undefined && $(this).attr(
                                    'lay-reqtext') !== undefined) {
                                    $(this).attr('placeholder', $(this).attr('lay-reqtext'));
                                }
                            }else{//todo 自定义必填项处理
                                var label = $(this).parent().prev();
                                if (label.is('label') && !label.hasClass('required')) {
                                    label.addClass('required');
                                }
                            }

                        });
                    }
                }
            };
            return exports;
        }(),
        /**
         * window窗体类（layer)
         */
        window: function () {
            var exports = {
                /**
                 * 打开
                 * @param options 参数
                 */
                open: function (options) {
                    //传入不是对象，则以URL方式访问
                    //1.本地，2.iframe模式
                    //var type = $.trim(options.content) != "[object Object]" ? 2 : 1;
                    var defaults = {
                        id: null,
                        type: 1,
                        skin: null,
                        move: true,//是否允许拖动，ture为允许
                        title: '系统窗口',
                        width: "500px",
                        height: "400px",
                        content: null,
                        shade: 0.3,
                        offset: ["100px"],
                        area: null,
                        btn: null,//['　确认　', '　关闭　'],//默认关闭按钮
                        btnAlign: 'c',//按钮居中
                        shadeClose: true,
                        closeBtn: 1,//关闭按钮 0：不显示，1：默认，2：右上角圆角
                        anim: 0,//弹出动画 0：默认，1：从上掉落，2：从最底部往上滑入，3：从左滑入，4：从左翻滚，5：渐显，6：抖动
                        callback: null,//确认回调函数
                        btn2: null,
                        btn3: null,
                        btn4: null,
                        btn5: null,
                        btn6: null,
                        success: null
                    };
                    var options = $.extend(defaults, options);
                    var _width = $(window).width() > parseInt(options.width.replace('px', '')) ? options.width : top.$(window).width() + 'px';
                    var _height = $(window).height() > parseInt(options.height.replace('px', '')) ? options.height : top.$(window).height() + 'px';
                    //所有layer弹出框在设置宽度高度时添加手机屏幕自适应代码：
                    if (navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)) {//如果是移动端，就使用自适应大小弹窗
                        _width = 'auto';
                        _height = 'auto';
                    } else {
                        //如果是PC端，根据用户设置的width和height显示。
                    }
                    var layerIdx = layer.open({
                        id: 'layer_id_' + options.id,//避免和实际id冲突
                        type: options.type,
                        skin: options.skin,
                        // move: options.move,
                        shade: options.shade,
                        title: options.title,
                        fix: false,
                        area: options.area || [_width, _height],
                        content: options.content,
                        btn: options.btn,
                        btnAlign: options.btnAlign,
                        shadeClose: options.shadeClose,
                        closeBtn: options.closeBtn,
                        anim: options.anim,
                        offset: options.offset,
                        yes: function (index, _layer) {
                            var layer_id = 'layer_id_' + options.id;
                            if (options.type == 2) {//iframe模式
                                var iframeWin = null;
                                // if (top.$('#' + layer_id + ' iframe').length > 0) {
                                // iframeWin = top.$('#' + layer_id + ' iframe')[0].contentWindow;
                                iframeWin = _layer.find('iframe')[0].contentWindow;
                                // }
                                options.callback(layer_id, index, iframeWin);
                            } else {//dom模式
                                options.callback(layer_id, index);
                            }
                        },
                        btn2: options.btn2,
                        btn3: options.btn3,
                        btn4: options.btn4,
                        btn5: options.btn5,
                        btn6: options.btn6,
                        success: options.success,
                        cancel: function () {
                            return true;
                        }
                    });
                    $(".layui-layer .layui-layer-title").append("<i class='shu'></i>");
                    return layerIdx;
                },
                tab: function (options) {
                    var defaults = {
                        id: null,
                        type: 1,
                        move: false,//是否允许拖动，ture为允许
                        tab: [{
                            title: 'TAB1',
                            content: null
                        }, {
                            title: 'TAB2',
                            content: null
                        }],
                        width: "800px",
                        height: "460px",
                        shade: 0.3,
                        btn: ['　确认　', '　关闭　'],
                        btnAlign: 'c',//按钮居中
                        shadeClose: true,
                        callback: null,//确认回调函数
                        success: null
                    };
                    var options = $.extend(defaults, options);
                    var _width = top.$(window).width() > parseInt(options.width.replace('px', '')) ? options.width : top.$(window).width() + 'px';
                    var _height = top.$(window).height() > parseInt(options.height.replace('px', '')) ? options.height : top.$(window).height() + 'px';
                    //所有layer弹出框在设置宽度高度时添加手机屏幕自适应代码：
                    if (navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)) {//如果是移动端，就使用自适应大小弹窗
                        _width = 'auto';
                        _height = 'auto';
                    } else {
                        //如果是PC端，根据用户设置的width和height显示。
                    }
                    layer.tab({
                        id: 'layer_id_' + options.id,//避免和实际id冲突
                        type: options.type,
                        // move: options.move,
                        shade: options.shade,
                        tab: [{
                            title: options.tab[0].title,
                            content: options.tab[0].content
                        }, {
                            title: options.tab[1].title,
                            content: options.tab[1].content
                        }],
                        fix: false,
                        area: [_width, _height],
                        btn: options.btn,
                        btnAlign: options.btnAlign,
                        shadeClose: options.shadeClose,
                        yes: function (index, _layer) {
                            var layer_id = 'layer_id_' + options.id;
                            if (options.type == 2) {//iframe模式
                                var iframeWin = null;
                                if ($('#' + layer_id + ' iframe').length > 0) {
                                    iframeWin = $('#' + layer_id + ' iframe')[0].contentWindow;
                                }
                                options.callback(layer_id, index, iframeWin);
                            } else {//dom模式
                                options.callback(layer_id, index);
                            }
                        },
                        success: options.success,
                        cancel: function () {
                            return true;
                        }
                    });
                    $(".layui-layer .layui-layer-title").append("<i class='shu'></i>");
                },
                /**
                 * 确认
                 * @param content   标题
                 * @param callBack  回调函数（确定）
                 */
                confirm: function (content, callBack) {
                    layer.confirm(content, {
                        icon: "fa-exclamation-circle",
                        title: "系统提示",
                        offset: ["200px"],
                        btn: ['确认', '取消'],
                        btnclass: ['btn btn-primary', 'btn btn-danger'],
                    }, function (idx) {
                        callBack(true, idx);
                    }, function (idx) {
                        callBack(false, idx);
                    });
                },
                /**
                 * 报警
                 * @param content
                 * @param type
                 */
                alert: function (content, type) {
                    var icon = "";
                    if (type == 'success' || type == '200') {
                        icon = "1";
                    }
                    if (type == 'error' || type == '999') {
                        icon = "2";
                    }
                    if (type == 'warning') {
                        icon = "3";
                    }
                    layer.alert(content, {
                        icon: icon,
                        title: "系统提示",
                        btn: ['确认'],
                        btnclass: ['btn btn-primary'],
                    });
                },
                /**
                 * 消息
                 * @param content
                 * @param type
                 */
                msg: function (content, type) {
                    if (type != undefined) {
                        var icon = "";
                        if (type == 'success' || type == "200") {
                            icon = "1";
                        }
                        if (type == 'error' || type == "999") {
                            icon = "2";
                        }
                        if (type == 'warning') {
                            icon = "3";
                        }
                        layer.msg(content, {icon: icon, time: 3000, shift: 5});
                    } else {
                        layer.msg(content);
                    }
                },
                /**
                 * 关闭
                 */
                close: function () {
                    //先得到当前iframe层的索引
                    var index = layer.getFrameIndex(window.name);
                    var $IsdialogClose = top.$("#layui-layer" + index).find('.layui-layer-btn').find("#IsdialogClose");
                    var IsClose = $IsdialogClose.is(":checked");
                    if ($IsdialogClose.length == 0) {
                        IsClose = true;
                    }
                    if (IsClose) {
                        layer.close(index);
                    } else {
                        location.reload();
                    }
                },
                /**
                 * 后台抛出的异常处理
                 * @param XMLHttpRequest
                 */
                thrown: function (XMLHttpRequest) {
                    if(XMLHttpRequest.responseJSON !=null){
                        ab.window.msg(XMLHttpRequest.responseJSON.msg || XMLHttpRequest.responseText, "error");
                    }else {
                        ab.window.msg(XMLHttpRequest.responseText, "error");
                    }
                }
            };
            return exports;
        }(),
        /**
         * ajax
         */
        ajax: function () {
            /**
             *
             */
            function transParams() {
                var cfg = arguments[0];
                // if ($.isArray(cfg.data)) {
                //     cfg.postParam = $.extend([], cfg.data);
                // } else {
                //     cfg.postParam = $.extend({}, cfg.data);
                // }
                cfg.postParam = $.extend({}, cfg.data);
                if (cfg.postType == "json") {
                    cfg.data = JSON.stringify(cfg.postParam);
                    cfg.contentType = "application/json;charset=utf-8";
                } else if (cfg.postType == "form") {
                    cfg.data = toFormValue(cfg.postParam);
                }
            }

            /**
             * form表单数据转换
             * @param a
             * @param traditional
             * @returns {*}
             */
            function toFormValue(a, traditional) {

                if (!a) {
                    return a;
                }
                var r20 = /%20/g;
                ///	<summary>
                ///		创建数组或对象的序列化表示形式(适合于在 URL
                ///		查询字符串或 Ajax 请求中使用)。
                ///	</summary>
                ///	<param name="a" type="Object">
                ///		要序列化的数组或对象。
                ///	</param>
                ///	<param name="traditional" type="Boolean">
                ///		一个指示是否执行传统的“浅表”序列化的布尔值。
                ///	</param>
                ///	<returns type="String" />

                var s = [];

                // Set traditional to true for jQuery <= 1.3.2 behavior.
                if (traditional === undefined) {
                    traditional = $.ajaxSettings.traditional;
                }
                // If an array was passed in, assume that it is an array of form elements.
                if ($.isArray(a)) {
                    // Serialize the form elements
                    $.each(a, function () {
                        add(this.name, this.value);
                    });

                } else {
                    // If traditional, encode the "old" way (the way 1.3.2 or older
                    // did it), otherwise encode params recursively.
                    for (var prefix in a) {
                        buildParams(prefix, a[prefix]);
                    }
                }
                // Return the resulting serialization
                return s.join("&").replace(r20, "+");

                function buildParams(prefix, obj) {
                    if ($.isArray(obj)) {
                        // Serialize array item.
                        $.each(obj, function (i, v) {
                            if (traditional) {
                                // Treat each array item as a scalar.
                                add(prefix, v);
                            } else {
                                // If array item is non-scalar (array or object), encode its
                                // numeric index to resolve deserialization ambiguity issues.
                                // Note that rack (as of 1.0.0) can't currently deserialize
                                // nested arrays properly, and attempting to do so may cause
                                // a server error. Possible fixes are to modify rack's
                                // deserialization algorithm or to provide an option or flag
                                // to force array serialization to be shallow.
                                buildParams(prefix + "[" + (typeof v === "object" || $.isArray(v) ? i : "") + "]", v);
                            }
                        });

                    } else if (!traditional && obj != null && typeof obj === "object") {
                        // Serialize object item.
                        $.each(obj, function (k, v) {
                            //buildParams(prefix + "[" + k + "]", v);
                            buildParams(prefix + "." + k, v);
                        });

                    } else {
                        // Serialize scalar item.
                        add(prefix, obj);
                    }
                }

                function add(key, value) {
                    // If value is a function, invoke it and return its value
                    value = $.isFunction(value) ? value() : value;
                    if (value == null) {
                        s[s.length] = encodeURIComponent(key) + "=";
                    } else {
                        s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
                    }
                }

            }

            /**
             * ajax 函数
             * @param param
             */
            var ajax = function () {
                var param = arguments[0];
                var options = {
                    url: param.url,
                    data: param.data || {},
                    type: param.type || "POST",
                    dataType: param.dataType || "json",
                    postType: param.postType || "form",
                    jsonp: param.jsonp || "callback",
                    async: param.async !== false,
                    contentType: param.contentType || "application/json",//"application/x-www-form-urlencoded",
                    statusCode: param.statusCode || {},
                    loadingEle: param.loadingEle || null,
                    loading: param.loading || "正在努力请求数据，请稍后...",
                    beforeSend: param.beforeSend || function () {
                    },
                    success: param.success || function () {
                    },
                    error: param.error || function () {
                    },
                    complete: param.complete || function () {
                    }
                };
                //构建参数
                // transParams(options);
                if (options.loadingEle != null)
                    options.loadingEle.mLoading({text: options.loading});
                $.ajax({
                    url: options.url,
                    data: options.data,
                    type: options.type,
                    async: options.async,
                    dataType: options.dataType,
                    contentType: options.contentType,
                    success: function (data, textStatus) {
                        if (typeof data == "string")
                            options.error.call(this, data, textStatus);
                        options.success.call(this, data, textStatus);
                        if (options.loadingEle != null)
                            options.loadingEle.mLoading("hide");
                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown) {
                        options.error.call(this, XMLHttpRequest, textStatus, errorThrown);
                        if (options.loadingEle != null)
                            options.loadingEle.mLoading("hide");
                    },
                    beforeSend: function (XMLHttpRequest) {
                        options.beforeSend.call(this, XMLHttpRequest);
                    },
                    complete: function (XMLHttpRequest, textStatus) {
                        options.complete.call(this, XMLHttpRequest, textStatus);
                    }
                });
            };
            return ajax;
        }(),
        /**
         * event 事件
         */
        events: {
            // 关闭当前选项卡
            closeThisTabs: function () {
                var $title = $('.layui-layout-admin .layui-body .layui-tab .layui-tab-title');
                if ($title.find('li').first().hasClass('layui-this')) {
                    return;
                }
                $title.find('li.layui-this').find(".layui-tab-close").trigger("click");
            },
            // 关闭其他选项卡
            closeOtherTabs: function () {
                $('.layui-layout-admin .layui-body .layui-tab .layui-tab-title li:gt(0):not(.layui-this)').find(".layui-tab-close").trigger("click");
            },
            // 关闭所有选项卡
            closeAllTabs: function () {
                $('.layui-layout-admin .layui-body .layui-tab .layui-tab-title li:gt(0)').find(".layui-tab-close").trigger("click");
            },
            // 关闭所有弹窗
            closeDialog: function () {
                layer.closeAll('page');
            }
        },

        /**
         * 判断是否为手机
         * @returns {boolean}
         */
        checkMobile: function () {
            var ua = navigator.userAgent.toLocaleLowerCase();
            var pf = navigator.platform.toLocaleLowerCase();
            var isAndroid = (/android/i).test(ua) || ((/iPhone|iPod|iPad/i).test(ua) && (/linux/i).test(pf))
                || (/ucweb.*linux/i.test(ua));
            var isIOS = (/iPhone|iPod|iPad/i).test(ua) && !isAndroid;
            var isWinPhone = (/Windows Phone|ZuneWP7/i).test(ua);
            var clientWidth = document.documentElement.clientWidth;
            if (!isAndroid && !isIOS && !isWinPhone && clientWidth > 1024) {
                return false;
            } else {
                return true;
            }
        },

    };

    // 所有ew-event
    $('body').on('click', '*[ew-event]', function () {
        var event = $(this).attr('ew-event');
        var te = ab.events[event];
        te && te.call(this, $(this));
    });

    exports("ab", ab);
});
layui.define(["jquery"], function (exports) {
    var $ = layui.$;

    var arraySlice = Array.prototype.slice,
        comparison = function (obj1, obj2) {
            var result = true;
            for (var pro in obj1) {
                if (obj1[pro] !== obj2[obj1]) {
                    result = true;
                    break;
                }
            }
            return result;
        }

    function MLoading(dom, options) {
        options = options || {};
        this.dom = dom;
        this.options = $.extend(true, {}, MLoading.defaultOptions, options);
        this.curtain = null;
        this.render().show();
    }

    MLoading.prototype = {
        constructor: MLoading,
        initElement: function () {
            var dom = this.dom,
                ops = this.options;
            var curtainElement = dom.children(".mloading"),
                bodyElement = curtainElement.children('.mloading-body'),
                barElement = bodyElement.children('.mloading-bar'),
                iconElement = barElement.children('.mloading-icon'),
                textElement = barElement.find(".mloading-text");
            if (curtainElement.length == 0) {
                // z-index：解决layer弹框不能遮罩的情况
                curtainElement = $('<div class="mloading" style="z-index: 20000101"></div>');
                dom.append(curtainElement);
            }
            if (bodyElement.length == 0) {
                bodyElement = $('<div class="mloading-body"></div>');
                curtainElement.append(bodyElement);
            }
            if (barElement.length == 0) {
                barElement = $('<div class="mloading-bar"></div>');
                bodyElement.append(barElement);
            }
            if (iconElement.length == 0) {
                var _iconElement = document.createElement(ops.iconTag);
                iconElement = $(_iconElement);
                iconElement.addClass("mloading-icon");
                barElement.append(iconElement);
            }
            if (textElement.length == 0) {
                textElement = $('<span class="mloading-text"></span>');
                barElement.append(textElement);
            }

            this.curtainElement = curtainElement;
            this.bodyElement = bodyElement;
            this.barElement = barElement;
            this.iconElement = iconElement;
            this.textElement = textElement;
            return this;
        },
        render: function () {
            var dom = this.dom,
                ops = this.options;
            this.initElement();
            if (dom.is("html") || dom.is("body")) {
                this.curtainElement.addClass("mloading-full");
            } else {
                this.curtainElement.removeClass("mloading-full");

                if (!dom.hasClass("mloading-container")) {
                    dom.addClass("mloading-container");
                }
            }
            if (ops.mask) {
                this.curtainElement.addClass("mloading-mask");
            } else {
                this.curtainElement.removeClass("mloading-mask");
            }
            if (ops.content != "" && typeof ops.content != "undefined") {
                if (ops.html) {
                    this.bodyElement.html(ops.content);
                } else {
                    this.bodyElement.text(ops.content);
                }
            } else {
                this.iconElement.attr("src", ops.icon);
                if (ops.html) {
                    this.textElement.html(ops.text);
                } else {
                    this.textElement.text(ops.text);
                }
            }

            return this;
        },
        setOptions: function (options) {
            options = options || {};
            var oldOptions = this.options;
            this.options = $.extend(true, {}, this.options, options);
            if (!comparison(oldOptions, this.options)) this.render();
        },
        show: function () {
            var dom = this.dom,
                ops = this.options,
                barElement = this.barElement;
            this.curtainElement.addClass("active");
            barElement.css({
                "marginTop": "-" + barElement.outerHeight() / 2 + "px",
                "marginLeft": "-" + barElement.outerWidth() / 2 + "px"
            });

            return this;
        },
        hide: function () {
            var dom = this.dom,
                ops = this.options
            g = this;
            setTimeout(function () {
                g.curtainElement.removeClass("active");
                if (!dom.is("html") && !dom.is("body")) {
                    dom.removeClass("mloading-container");
                }
            }, 200);

            return this;
        },
        destroy: function () {
            var dom = this.dom,
                ops = this.options;
            this.curtainElement.remove();
            if (!dom.is("html") && !dom.is("body")) {
                dom.removeClass("mloading-container");
            }
            dom.removeData(MLoading.dataKey);
            return this;
        }
    };
    MLoading.dataKey = "MLoading";
    MLoading.defaultOptions = {
        text: "加载中...",
        iconTag: "img",
        icon: "",
        html: false,
        content: "",//设置content后，text和icon设置将无效
        mask: true//是否显示遮罩（半透明背景）
    };

    $.fn.mLoading = function (options) {
        var ops = {},
            funName = "",
            funArgs = [];
        if (typeof options === "object") {
            ops = options;
        } else if (typeof options === "string") {
            funName = options;
            funArgs = arraySlice.call(arguments).splice(0, 1);
        }
        return this.each(function (i, element) {
            var dom = $(element),
                plsInc = dom.data(MLoading.dataKey);
            if (!plsInc) {
                plsInc = new MLoading(dom, ops);
            }

            if (funName) {
                var fun = plsInc[funName];
                if (typeof fun === "function") {
                    fun.apply(plsInc, funArgs);
                }
            }
        });
    }
});
